package com.invengo.library_rfid.analyze.impl;



import com.invengo.library_rfid.analyze.ConvertUtil;
import com.invengo.library_rfid.analyze.EPCStrategy;
import com.invengo.library_rfid.analyze._EpcRuleTag;

import java.io.Serializable;

public class CollegesEPCStrategyImpl implements EPCStrategy, Serializable {
    @Override
    public _EpcRuleTag getRule() {
        return _EpcRuleTag.RULE_COLLEGES;
    }

    @Override
    public String analyzeShelf(String epc) {
        System.out.println("高校模型开始解析shelf："+epc);
        byte[] bytes = strToByte(epc);
        int type = getType(bytes);
        if (epc.length() < 20) {
            return "";
        }
        if (type == 0) {
            System.out.println("编码方式 96位");
            return getShelf96(epc);
        } else if (type == 1) {
            System.out.println("编码方式 128位");
            return "";
        } else {
            return "";
        }
    }

    private String getShelf96(String epc) {
        String strEpc2 = ConvertUtil.str16ToStr2(epc);
        int barCodeLen = Integer.parseInt(strEpc2.substring(36 - 32, 40 - 32), 2);
        String barCode = "";
        char barCodeLast1 = (char) Integer.parseInt(strEpc2.substring(44 - 32, 48 - 32) + strEpc2.substring(32 - 32, 36 - 32), 2);
        char barCode3 = (char) (Integer.parseInt(strEpc2.substring(54 - 32, 56 - 32) + strEpc2.substring(40 - 32, 44 - 32), 2) + 48);
        char barCode2 = (char) (Integer.parseInt(strEpc2.substring(48 - 32, 54 - 32), 2) + 48);
        char barCode4 = (char) (Integer.parseInt(strEpc2.substring(70 - 32, 72 - 32) + strEpc2.substring(56 - 32, 58 - 32), 2) + 48);
        char barCode1 = (char) (Integer.parseInt(strEpc2.substring(59 - 32, 64 - 32), 2) + 48);
        String barCode5ToLast2 = "" + (Integer.parseInt(strEpc2.substring(88 - 32, 96 - 32) +
                strEpc2.substring(80 - 32, 88 - 32) +
                strEpc2.substring(72 - 32, 80 - 32) +
                strEpc2.substring(64 - 32, 70 - 32), 2));
        int i = barCodeLen - 5 - barCode5ToLast2.length();
        String barCode5T2 = "";
        if (i > 0) {
            for (int i1 = 0; i1 < i; i1++) {
                barCode5ToLast2 = "0" + barCode5ToLast2;
            }
            barCode5T2 = barCode5ToLast2;
        } else if (i < 0) {
            barCode5T2 = barCode5ToLast2.substring(0, barCodeLen - 5);
        } else {
            barCode5T2 = barCode5ToLast2;
        }
        return barCode + barCode1 + barCode2 + barCode3 + barCode4 + barCode5T2;
    }


    @Override
    public String analyzeBook(String epc) {
        System.out.println("高校模型开始解析book："+epc);
        byte[] bytes = strToByte(epc);
        int type = getType(bytes);
        if (epc.length() < 20) {
            throw new IllegalArgumentException("epc长度低于20位");
        }
        if (type == 0) {
            return getBook96(epc);
        } else if (type == 1) {
            String tagBeanBy128Bit = ruleBy128Bit(epc);
            return tagBeanBy128Bit;
        } else {
            throw new IllegalArgumentException("epc长度低于20位");
        }
    }

    private String getBook96(String epc) {
        String strEpc2 = ConvertUtil.str16ToStr2(epc);

        int barCodeLen = Integer.parseInt(strEpc2.substring(36, 40), 2);

        String barCode = "";
        char barCodeLast1 = (char) Integer.parseInt(strEpc2.substring(44, 48) + strEpc2.substring(32, 36), 2);

        char barCode3 = (char) (Integer.parseInt(strEpc2.substring(54, 56) + strEpc2.substring(40, 44), 2) + 48);

        char barCode2 = (char) (Integer.parseInt(strEpc2.substring(48, 54), 2) + 48);

        char barCode4 = (char) (Integer.parseInt(strEpc2.substring(70, 72) + strEpc2.substring(56, 58), 2) + 48);

        char barCode1 = (char) (Integer.parseInt(strEpc2.substring(59, 64), 2) + 48);

        String barCode5ToLast2 = "" + (Integer.parseInt(strEpc2.substring(88, 96) +
                strEpc2.substring(80, 88) +
                strEpc2.substring(72, 80) +
                strEpc2.substring(64, 70), 2));
        int i = barCodeLen - 5 - barCode5ToLast2.length();
        String barCode5T2 = "";
        if (i > 0) {
            for (int i1 = 0; i1 < i; i1++) {
                barCode5ToLast2 = "0" + barCode5ToLast2;
            }
            barCode5T2 = barCode5ToLast2;
        } else if (i < 0) {
            barCode5T2 = barCode5ToLast2.substring(0, barCodeLen - 5);
        } else {
            barCode5T2 = barCode5ToLast2;
        }
        return barCode + barCode1 + barCode2 + barCode3 + barCode4 + barCode5T2 + barCodeLast1;
    }


    public static int getType(byte[] bytes) {
        byte b = (byte) ((int) bytes[1] >> 6);
        byte c = (byte) 3;
        int l = b & c;
        return l;
    }

    public static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    public static byte[] strToByte(String hexString) {
        if (hexString == null || hexString.equals("")) {
            return null;
        }
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 0 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }

    /**
     * Convert char to byte
     *
     * @param c char
     * @return byte
     */
    public static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }

    private static String ruleBy128Bit(String epc) {
        String substring = epc.substring(10, 26);
        char[] chars = substring.toCharArray();
        String barcode = "";
        for (int i = 0; i < chars.length; i++) {
            if (i % 2 == 1) {
                barcode += chars[i];
            }
        }
        return barcode;
    }

    private static String ruleBy96Bit(String epc) {
        String strEpc2 = ConvertUtil.str16ToStr2(epc);
//        Log.d("strEpc2len>>>>>>>", strEpc2.length() + "");

        int barCodeLen = Integer.parseInt(strEpc2.substring(36 - 32, 40 - 32), 2);
        System.out.println("条码长度：: " + barCodeLen + "");

        String barCode = "";
        char barCodeLast1 = (char) Integer.parseInt(strEpc2.substring(44 - 32, 48 - 32) + strEpc2.substring(32 - 32, 36 - 32), 2);
        System.out.println("最后一位：: " + barCodeLast1 + "");

        char barCode3 = (char) (Integer.parseInt(strEpc2.substring(54 - 32, 56 - 32) + strEpc2.substring(40 - 32, 44 - 32), 2) + 48);
        System.out.println("第三位：: " + barCode3 + "");

        char barCode2 = (char) (Integer.parseInt(strEpc2.substring(48 - 32, 54 - 32), 2) + 48);
        System.out.println("第二位：: " + barCode2 + "");

        char barCode4 = (char) (Integer.parseInt(strEpc2.substring(70 - 32, 72 - 32) + strEpc2.substring(56 - 32, 58 - 32), 2) + 48);
        System.out.println("第四位：: " + barCode4 + "");

        char barCode1 = (char) (Integer.parseInt(strEpc2.substring(59 - 32, 64 - 32), 2) + 48);
        System.out.println("第一位：: " + barCode1 + "");

        String barCode5ToLast2 = "" + (Integer.parseInt(strEpc2.substring(88 - 32, 96 - 32) +
                strEpc2.substring(80 - 32, 88 - 32) +
                strEpc2.substring(72 - 32, 80 - 32) +
                strEpc2.substring(64 - 32, 70 - 32), 2));
        System.out.println("第五位至倒数第二位：: " + barCode5ToLast2 + "");
        int i = barCodeLen - 5 - barCode5ToLast2.length();
        String barCode5T2 = "";
        if (i > 0) {
            for (int i1 = 0; i1 < i; i1++) {
                barCode5ToLast2 = "0" + barCode5ToLast2;
            }
            barCode5T2 = barCode5ToLast2;
        } else if (i < 0) {
            barCode5T2 = barCode5ToLast2.substring(0, barCodeLen - 5);
        } else {
            barCode5T2 = barCode5ToLast2;
        }
        return barCode + barCode1 + barCode2 + barCode3 + barCode4 + barCode5T2;
    }
}
